package sunyu.controller.shiro;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import sunyu.controller.common.CommonController;
import sunyu.kit.common.LogKit;
import sunyu.kit.common.StringKit;
import sunyu.kit.encrypt.EncryptKit;
import sunyu.mapper.shiro.pojo.Role;
import sunyu.mapper.shiro.pojo.User;
import sunyu.service.shiro.RoleService;
import sunyu.service.shiro.UserService;

import javax.annotation.Resource;
import java.util.*;

/**
 * 用户相关Controller
 *
 * @author 孙宇
 */
@Controller
@RequestMapping("/shiro/user")
public class UserController extends CommonController {

    private static final Logger logger = LogKit.getLogger();

    @Resource(name = "userService")
    private UserService userService;

    @Resource(name = "roleService")
    private RoleService roleService;

    /**
     * 主要是用来前台提交表单，自动转换成javaBean
     * <p>
     * 例如前台表单
     * <p>
     * user.name=xxx
     * <p>
     * user.age=11
     * <p>
     * 会自动转换成UserBean
     *
     * @param binder
     */
    @InitBinder("user")
    public void initBinderResource(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("user.");
    }

    /**
     * 跳转到列表页面
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:user:list"})
    public String list(Model model) {
        return "/shiro/user/list";
    }

    /**
     * 获得用户数据
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:user:list"})
    @ResponseBody
    public Map<String, Object> list(@RequestBody Map<String, Object> params) {
        Map<String, Object> p = new HashMap<>();
        Page page = new Page();
        if (params.get("pageNum") != null) {
            page.setPageNum(Integer.parseInt(params.get("pageNum").toString()));
        }
        if (params.get("pageSize") != null) {
            page.setPageSize(Integer.parseInt(params.get("pageSize").toString()));
        }
        if (params.get("sort") != null) {
            page.setOrderBy(params.get("sort") + " " + params.get("order"));
        }
        List<User> roles = userService.select(page, null);

        PageInfo pageInfo = new PageInfo(roles);

        p.put("total", pageInfo.getTotal());
        p.put("rows", pageInfo.getList());

        return p;
    }

    /**
     * 跳转到新增页面
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/insert", method = RequestMethod.GET)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:user:insert"})
    public String insert(Model model) {
        return insertPage(model);
    }

    /**
     * 跳转到insert页面
     *
     * @param model
     * @return
     */
    private String insertPage(Model model) {
        model.addAttribute("action", "insert");//告诉前台页面的form，准备调用insert操作

        getUserRoles(model);

        return "/shiro/user/form";
    }

    /**
     * 新增
     *
     * @param user
     * @param roleIds
     * @param model
     * @return
     */
    @RequestMapping(value = "/insert", method = RequestMethod.POST)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:user:insert"})
    public String insert(@ModelAttribute("user") User user,
                         String roleIds,
                         Model model) {
        Map<String, Object> params = new HashMap<String, Object>() {{
            put("loginName", user.getLoginName());
        }};
        if (userService.count(params) > 0) {
            model.addAttribute("errMsg", "用户登陆名称已存在！");
            return insertPage(model);
        }

        user.setId(UUID.randomUUID().toString());
        user.setCreated(new Date());
        user.setModified(user.getCreated());

        user.setLoginPassword(EncryptKit.md5(user.getLoginPassword()));//密码加密

        userService.insert(user, roleIds);

        return "redirect:/shiro/user/list";
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/delete/{id}")
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:user:delete"})
    public String delete(@PathVariable("id") String id) {
        userService.delete(id);
        return "redirect:/shiro/user/list";
    }

    /**
     * 跳转到修改页面
     *
     * @param model
     * @param id
     * @return
     */
    @RequestMapping(value = "/update/{id}", method = RequestMethod.GET)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:user:update"})
    public String update(Model model,
                         @PathVariable("id") String id) {
        User user = userService.selectById(id);
        return updatePage(model, user);
    }

    private String updatePage(Model model,
                              User user) {
        model.addAttribute("user", user);

        model.addAttribute("action", "update");//告诉前台页面的form，准备调用update操作

        getUserRoles(model);

        String roleIds = userService.getRoleIds(user.getId());
        if (StringKit.isNotBlank(roleIds)) {
            model.addAttribute("roleIds", roleIds);//用户的角色
        }

        return "/shiro/user/form";
    }

    /**
     * 前台需要的用户的所有角色
     *
     * @param model
     */
    private void getUserRoles(Model model) {
        Page page = new Page();
        page.setOrderBy("modified desc");
        List<Role> roles = roleService.select(page, null);
        model.addAttribute("roles", roles);
    }

    /**
     * 修改
     *
     * @param user
     * @param roleIds
     * @param model
     * @return
     */
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:user:update"})
    public String update(@ModelAttribute("user") User user,
                         String roleIds,
                         Model model) {

        Map<String, Object> params = new HashMap<String, Object>() {{
            put("loginName", user.getLoginName());
        }};
        List<User> users = userService.select(null, params);
        if (users != null && users.size() > 0) {
            for (User u : users) {
                if (!u.getId().equals(user.getId())) {//说明用户登陆名称已经有人占用了
                    model.addAttribute("errMsg", "登录名已经存在！");
                    return updatePage(model, user);
                }
            }
        }

        User oldUser = userService.selectById(user.getId());
        if (oldUser.getLoginPassword().equals(user.getLoginPassword())) {//如果数据库里面的密码跟页面传递过来的密码字符串相同，说明用户没有修改密码
            user.setLoginPassword(null);//赋值为空，不修改密码
        } else {
            user.setLoginPassword(EncryptKit.md5(user.getLoginPassword()));//重新加密
        }

        user.setModified(new Date());
        userService.update(user, roleIds);

        return "redirect:/shiro/user/list";
    }

}
